/*
 * Copyright (c) 2010, Jim Hollinger
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *   * Neither the name of Jim Hollinger nor the names of its contributors
 *     may be used to endorse or promote products derived from this
 *     software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#ifndef COMMON_KMLIO_KMLWRITER_H_
#define COMMON_KMLIO_KMLWRITER_H_

#include <string>
#include <vector>

namespace kmlio {

/**
 ****************************************************************************
 * @brief  A class to facilitate the creation of KML files.
 *
 *  A typical use of this class is shown below.
 *   \code
 *    kmlio::KmlWriter kmlWriter;
 *    kmlWriter.open("example.kml");
 *    kmlWriter.addXmlDeclaration();
 *    kmlWriter.addKml();
 *    kmlWriter.addDocument("Example", "Example line string with one point");
 *    kmlWriter.addStyle("transPurpleLineGreenPoly");
 *    kmlWriter.addLineStyle("7fff00ff", 4);
 *    kmlWriter.addPolyStyle("7f00ff00");
 *    kmlWriter.close1();  // style
 *    kmlWriter.addPlacemark("", "", "#transPurpleLineGreenPoly");
 *    kmlWriter.addLineString("clampToGround");
 *    kmlWriter.addCoordinates();
 *    kmlWriter.addCoordinate(37.2137, -80.4376);
 *    kmlWriter.addCoordinate(37.2136, -80.4376);
 *    kmlWriter.addCoordinate(37.2136, -80.4377);
 *    kmlWriter.addCoordinate(37.2137, -80.4376);
 *    kmlWriter.close();
 *   \endcode
 *  The above code will generate the following output.
 *   \code
 *    <?xml version="1.0" encoding="UTF-8"?>
 *    <kml xmlns="http://www.opengis.net/kml/2.2">
 *      <Document>
 *        <name>Example</name>
 *        <description>Example line string with one point</description>
 *        <Style id="transPurpleLineGreenPoly">
 *          <LineStyle>
 *            <color>7fff00ff</color>
 *            <width>4.0</width>
 *          </LineStyle>
 *          <PolyStyle>
 *            <color>7f00ff00</color>
 *          </PolyStyle>
 *        </Style>
 *        <Placemark>
 *          <styleUrl>#transPurpleLineGreenPoly</styleUrl>
 *          <visibility>1</visibility>
 *          <LineString>
 *            <altitudeMode>clampToGround</altitudeMode>
 *            <tessellate>1</tessellate>
 *            <coordinates>
 *              -80.437700000000,37.213600000000
 *              -80.437600000000,37.213600000000
 *              -80.437600000000,37.213700000000
 *              -80.437700000000,37.213600000000
 *            </coordinates>
 *          </LineString>
 *        </Placemark>
 *      </Document>
 *    </kml>
 *   \endcode
 *  The above output can be pasted into the text box at
 *    http://kml-samples.googlecode.com/svn/trunk/interactive/index.html
 *    to be viewed interactively.
 ****************************************************************************
**/
class KmlWriter {
  public:
    KmlWriter();
    ~KmlWriter();

    bool open(const std::string &filename);
    bool addXmlDeclaration();
    bool addKml();
    bool addDocument(const std::string &name, const std::string &description);
    bool addPlacemark(const std::string &name, const std::string &description,
                      const std::string &styleUrl, int visibility = 1);
    bool addLineString(const std::string &altitudeMode, int tessellate = 1);
    bool addStyle(const std::string &id);
    bool addLineStyle(const std::string &color, double width);
    bool addPolyStyle(const std::string &color);
    bool addCoordinates();
    bool addCoordinate(double latitude_degN, double longitude_degE,
                       double altitude_m = 0.0);

    bool close1();
    bool close();

    void setPretty(bool pretty_flag = true);

    static bool unitTest();

  protected:
    void add(const char *format, ...);

  protected:
    FILE   *fp;                 ///< FILE pointer to which the output is written
    bool    pretty_flag;        ///< True causes XML tags to be indented
    std::vector<std::string> stack;  ///< The XML element stack
};

}  // namespace kmlio

#endif  // COMMON_KMLIO_KMLWRITER_H_
